﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MotaWeb.Models.Interfaces;
using System.Web.Security;

namespace MotaWeb.Models
{
    public class MotaRepository : IMotaWebRepository
    {
        private MotaDBDataContext db = new MotaDBDataContext();

        #region SiteUsers
        public IQueryable<ISiteUser> FindAllSiteUsers()
        {
            var siteUsers =
                from u in db.SiteUsers
                select new MotaSiteUser
                {
                    Id = u.Id,
                    ProviderUserKey = u.ProviderUserKey,
                    FirstName = u.FirstName,
                    LastName = u.LastName
                };
            return (IQueryable<ISiteUser>)siteUsers;
        }

        public ISiteUser FindSiteUser(int id)
        {
            MotaSiteUser siteUser = null;
            var matches =
                from u in db.SiteUsers
                 where u.Id == id
                 select new MotaSiteUser
                 {
                     Id = u.Id,
                     ProviderUserKey = u.ProviderUserKey,
                     FirstName = u.FirstName,
                     LastName = u.LastName
                 };
            if (matches.Count() > 0)
            {
                siteUser = matches.First();
            }
            return siteUser;
        }

        public ISiteUser SiteUserFromMembershipUser(MembershipUser user)
        {
            MotaSiteUser siteUser = null;

            var matches =
                from u in db.SiteUsers
                 where u.ProviderUserKey == (Guid)user.ProviderUserKey
                 select new MotaSiteUser
                 {
                     Id = u.Id,
                     ProviderUserKey = u.ProviderUserKey,
                     FirstName = u.FirstName,
                     LastName = u.LastName
                 };
            if (matches.Count() > 0)
            {
                siteUser = matches.First();
                siteUser.UserName = user.UserName;
            }
            else
            {
                siteUser = new MotaSiteUser()
                    {
                        ProviderUserKey = (Guid)user.ProviderUserKey,
                        UserName = user.UserName,
                    };
            }
            return siteUser;
        }

        public void UpdateSiteUser(ISiteUser userToUpdate)
        {
            var userMatches =
                from su in db.SiteUsers
                where su.Id == userToUpdate.Id
                select su;

            if (userMatches.Count() == 0)
            {
                CreateSiteUser(userToUpdate.FirstName, userToUpdate.LastName, userToUpdate.ProviderUserKey);
            }
            else
            {
                var original = userMatches.FirstOrDefault();
                original.FirstName = userToUpdate.FirstName;
                original.LastName = userToUpdate.LastName;
                original.ProviderUserKey = userToUpdate.ProviderUserKey;
                db.SubmitChanges();
            }

        }

        public SiteUser CreateSiteUser(string firstName, string lastName, Guid providerUserKey)
        {
            var siteUser = new SiteUser()
            {
                FirstName = firstName,
                LastName = lastName,
                ProviderUserKey = providerUserKey
            };

            db.SiteUsers.InsertOnSubmit(siteUser);
            db.SubmitChanges();
            return siteUser;
        }

        #endregion

        #region Quotes
        public IQueryable<Quote> FindAllQuotes()
        {
            return from q in db.Quotes
                   select q;
        }

        public Quote FindQuote(DateTime forDate)
        {
            return
                (from q in db.Quotes
                 where
                     q.EffectiveDate <= forDate &&
                     q.ExpirationDate >= forDate
                 select q).First();

        }
        #endregion

        #region Announcements
        public IQueryable<Announcement> FindAllAnnouncements()
        {
            return from a in db.Announcements
                   orderby a.EffectiveDate
                   select a;
        }

        public Announcement FindAnnouncement(DateTime forDate)
        {
            Announcement announcementMatch = null;
            var matches =
                from a in db.Announcements
                where
                    a.EffectiveDate <= forDate &&
                    a.ExpirationDate >= forDate
                select a;

            if (matches.Count() > 0)
                announcementMatch = matches.First();

            return announcementMatch;
        }

        public Announcement FindAnnouncement(int id)
        {
            return (from a in db.Announcements
                    where a.Id == id
                    select a).First();
        }

        public Announcement CreateAnnouncement(string message, DateTime effectiveDate, DateTime expirationDate)
        {
            var a = new Announcement()
            {
                Message = message,
                EffectiveDate = effectiveDate,
                ExpirationDate = expirationDate
            };
            db.Announcements.InsertOnSubmit(a);
            db.SubmitChanges();
            return a;
        }

        public void EditAnnouncement(int id, string message, DateTime effectiveDate, DateTime expirationDate)
        {
            var originalAnnouncment =
                (from a in db.Announcements
                 where a.Id == id
                 select a).First();

            originalAnnouncment.Message = message;
            originalAnnouncment.EffectiveDate = effectiveDate;
            originalAnnouncment.ExpirationDate = expirationDate;
            db.SubmitChanges();
        }

        public void DeleteAnnouncement(int id)
        {
            var announcement =
                (from a in db.Announcements
                 where a.Id == id
                 select a).First();

            db.Announcements.DeleteOnSubmit(announcement);
            db.SubmitChanges();
        }
        #endregion

        #region Biographies
        public IQueryable<Biography> FindBiographies()
        {
            return from b in db.Biographies
                   select b;
        }

        public IQueryable<Biography> FindBiographies(bool isApproved)
        {
            return from b in db.Biographies
                   where b.IsApproved == isApproved
                   select b;
        }

        public Biography FindBiography(int id)
        {
            return (from b in db.Biographies
                    where b.Id == id
                    select b).First();
        }

        public Biography FindBiography(string userName)
        {
            var matches = from b in db.Biographies
                          where b.UserName == userName
                          select b;

            if (matches.Count() > 0)
                return matches.First();
            else
                return null;
        }

        public IQueryable<Biography> FindPendingBiographies()
        {
            return from b in db.Biographies
                   where b.IsApproved == false
                   select b;
        }

        public Biography CreateBiography(string biographyText, string userName, bool isApproved)
        {
            var b = new Biography()
            {
                BiographyText = biographyText,
                UserName = userName,
                IsApproved = isApproved
            };
            db.Biographies.InsertOnSubmit(b);
            db.SubmitChanges();
            return b;
        }

        public void EditBiography(int id, string biographyText, bool isApproved)
        {
            var original =
                (from b in db.Biographies
                 where b.Id == id
                 select b).First();

            original.BiographyText = biographyText;
            original.IsApproved = isApproved;
            db.SubmitChanges();
        }

        public void DeleteBiography(int id)
        {
            var biography =
                (from b in db.Biographies
                 where b.Id == id
                 select b).First();
            db.Biographies.DeleteOnSubmit(biography);
            db.SubmitChanges();
            throw new NotImplementedException();
        }
        #endregion

        public void Save()
        {
            db.SubmitChanges();
        }
    }
}
